import os, sys

parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 4)))
sys.path.insert(0, parent_path)

# from queue import Queue
from threading import Thread
from typing import *
import cv2, time, traceback
from core.utils.logger import logging

class BaseProcessor():
    """status状态机
    状态机包含三个值:
    0: close状态, 默认的状态
    1: ready状态, 初始化完成的状态
    2: running状态, 运行中
    """
    status = 0
    def __init__(self,keys) -> None:
        self.keys = keys
        pass
    
    def init_check(self):
        """用于任务执行前的初始化检查，避免有错漏的参数
        初始化检查结束的模块, 会进入ready状态
        """
        assert self.status == 0
        self._init_check()
        self.status = 1
        
    def _init_check(self):
        return 
        raise NotImplementedError("This method should be overridden. from {}".format(self.__class__.__name__))

    def set(self, data:Dict={}):
        """用于任务设置
        input:
            data: 流转数据box
        sample:
            data = {
                "input_data": np.ndarray([...])
            }
            if data.get("input_data",false):
                self.data = data["input_data"]
        
        set函数中必须使用dict.get的形式获取数据，以避免被替换掉不必要的数据
        并且只有在standby状态下(status==0)才可以进行设置
        """
        assert self.status == 0
        self._set(data)

    def _set(self, data:Dict):
        pass

    def __call__(self, data:Dict) -> Dict:
        assert self.status == 2
        data = self._call(data)
        return data

    def _call(self, data:Dict)->Dict:
        raise NotImplementedError("This method should be overridden.from {}".format(self.__class__.__name__))

    def start(self):
        self.init_check()
        self._start()
        self.status = 2

    def _start(self):
        pass

    def close(self):
        if self.status == 0:
            logging.warning("{} repeated close".format(self.__class__.__name__))
            return
        self._close()
        self.status = 0

    def _close(self):
        pass
    
    def is_close(self):
        return self.status == 0
    
    def is_running(self):
        return self.status == 2
    
    def is_standby(self):
        return self.status == 1